home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
forms
/
FORMS
/
menu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
7KB
|
264 lines
/*
* menu.c
*
* Forms Object class: MENU
*
* Written by: Mark Overmars and Trevor Paquette
*
* Version 2.2 a
* Date: Jun 28, 1993
*/
#include <malloc.h>
#include <strings.h>
#include "gl/device.h"
#include "gl/gl.h"
#include "forms.h"
/* Object specific information */
typedef struct{
long val; /* last menu item selected */
int numitems; /* number of items in menu */
char *items[FL_MENU_MAXITEMS+1]; /* individual menu items */
long mode[FL_MENU_MAXITEMS+1]; /* menu item mode */
char *shortcut[FL_MENU_MAXITEMS+1]; /* the shortcuts for the items */
int showsymbol; /* whether menu symbol should be shown */
} SPEC;
static int do_menu(FL_OBJECT *ob)
/* Creates the menu and shows it. Returns the item selected. */
{
int i; /* Counter */
long menu; /* The menu */
int val;
SPEC *sp = ((SPEC *)(ob->spec));
menu = newpup();
for (i=1; i<=sp->numitems;i++) addtopup(menu,sp->items[i]);
for (i=1; i<=sp->numitems;i++) setpup(menu, i, sp->mode[i]);
val = (int) dopup(menu);
freepup(menu);
return val;
}
static int handle_menu(FL_OBJECT *ob,int event,float mx,float my,char key)
/* Handles an event, returns whether value has changed. */
{
SPEC *sp = ((SPEC *)(ob->spec));
int i, col;
char shortcut[4];
switch (event)
{
case FL_DRAW:
/* Draw the object */
if ((ob->type == FL_PUSH_MENU && ob->pushed) ||
(ob->type == FL_TOUCH_MENU && ob->belowmouse))
col = ob->col2;
else
col = ob->col1;
fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,col,FL_MENU_BW);
fl_drw_text(ob->align,ob->x,ob->y,ob->w,ob->h,
ob->lcol,ob->lsize,ob->lstyle,ob->label);
if (sp->showsymbol)
fl_drw_text(0,ob->x+ob->w-0.8*ob->h,ob->y+0.2*ob->h,
0.6*ob->h,0.6*ob->h,col,0.0,0,"@menu");
return 0;
case FL_ENTER:
if (ob->type == FL_TOUCH_MENU)
{
fl_redraw_object(ob);
sp->val = do_menu(ob);
}
return 0;
case FL_LEAVE:
fl_redraw_object(ob);
return (ob->type == FL_TOUCH_MENU && sp->val != -1);
case FL_PUSH:
if (ob->type == FL_PUSH_MENU)
{
fl_redraw_object(ob);
sp->val = do_menu(ob);
qenter(MOUSE1,0); /* dopup eats up this event */
}
return 0;
case FL_RELEASE:
fl_redraw_object(ob);
return (ob->type == FL_PUSH_MENU && sp->val != -1);
case FL_SHORTCUT:
i = 0;
if (key >=128)
{shortcut[i++] = '#'; key -= 128;}
if (key <=26)
{shortcut[i++] = '^'; shortcut[i++] = key+'a'-1;}
else
shortcut[i++] = key;
shortcut[i] = '\0';
for (i=1; i<= sp->numitems; i++)
if (strstr(sp->shortcut[i],shortcut) != NULL && !(sp->mode[i] & PUP_GREY))
{ sp->val = i; return 1;}
return 0;
case FL_FREEMEM:
for (i=1; i <= sp->numitems;i++)
{ free(sp->items[i]); free(sp->shortcut[i]); }
free(ob->spec);
return 0;
default:
return 0;
}
}
/*-------------------------------------------*/
FL_OBJECT *fl_create_menu(int type,float x,float y,float w,float h,char label[])
/* creates an object */
{
FL_OBJECT *ob;
SPEC *sp;
ob = fl_make_object(FL_MENU,type,x,y,w,h,label,handle_menu);
ob->boxtype = FL_MENU_BOXTYPE;
ob->col1 = FL_MENU_COL1;
ob->col2 = FL_MENU_COL2;
ob->lcol = FL_MENU_LCOL;
ob->align = FL_MENU_ALIGN;
ob->spec = (int *) fl_malloc(sizeof(SPEC));
sp = ((SPEC *)(ob->spec));
sp->val = 0;
sp->numitems = 0;
sp->showsymbol = 0;
return ob;
}
FL_OBJECT *fl_add_menu(int type, float x, float y, float w, float h, char label[])
/* Adds an object */
{
FL_OBJECT *ob;
ob = fl_create_menu(type,x,y,w,h,label);
fl_add_object(fl_current_form,ob);
return ob;
}
/*-------------------------------------*/
void fl_clear_menu(FL_OBJECT *ob)
/* Clears the menu object */
{
int i;
SPEC *sp = ((SPEC *)(ob->spec));
sp->val = 0;
for (i=1; i <= sp->numitems; i++)
{ free(sp->items[i]); free(sp->shortcut[i]); sp->mode[i] = PUP_NONE; }
sp->numitems = 0;
}
static void addto_menu(FL_OBJECT *ob, char str[])
/* Adds a line to the menu item. */
{
SPEC *sp = ((SPEC *)(ob->spec));
if (sp->numitems >= FL_MENU_MAXITEMS) return;
sp->numitems++;
sp->items[sp->numitems] = (char *) fl_malloc(FL_MENU_MAXSTR+1);
strncpy(sp->items[sp->numitems],str,FL_MENU_MAXSTR);
sp->items[sp->numitems][FL_MENU_MAXSTR] = '\0';
sp->shortcut[sp->numitems] = (char *) fl_malloc(1);
sp->shortcut[sp->numitems][0] = '\0';
sp->mode[sp->numitems] = PUP_NONE;
}
void fl_set_menu(FL_OBJECT *ob, char menustr[])
/* Sets the menu to a particular menu string */
{
fl_clear_menu(ob);
fl_addto_menu(ob, menustr);
}
void fl_addto_menu(FL_OBJECT *ob, char menustr[])
/* Adds a line to the menu item. */
{
char ttt[256];
int i = 0, j = 0;
while (menustr[i] != '\0')
{
if (menustr[i] == '|')
{ ttt[j] = '\0'; addto_menu(ob, ttt); j = 0; }
else
ttt[j++] = menustr[i];
i++;
}
if (j != 0) { ttt[j] = '\0'; addto_menu(ob, ttt);}
}
void fl_replace_menu_item(FL_OBJECT *ob, int numb, char str[])
/* Replaces a line in the menu item. */
{
SPEC *sp = ((SPEC *)(ob->spec));
if (numb<1 || numb > sp->numitems) return;
strncpy(sp->items[numb],str,FL_MENU_MAXSTR);
sp->items[numb][FL_MENU_MAXSTR] = '\0';
}
void fl_delete_menu_item(FL_OBJECT *ob, int numb)
/* Removes a line from the menu item. */
{
int i;
SPEC *sp = ((SPEC *)(ob->spec));
if (numb<1 || numb >sp->numitems) return;
free(sp->items[numb]);
free(sp->shortcut[numb]);
for (i=numb; i<sp->numitems;i++)
{
sp->items[i] = sp->items[i+1];
sp->mode[i] = sp->mode[i+1];
sp->shortcut[i] = sp->shortcut[i+1];
}
sp->mode[sp->numitems] = PUP_NONE;
sp->numitems--;
}
/*------------------------------------------*/
void fl_set_menu_item_shortcut(FL_OBJECT *ob, int numb, char str[])
{
SPEC *sp = ((SPEC *)(ob->spec));
char sss[1024];
int i;
sp->shortcut[numb] = (char *) realloc(sp->shortcut[numb],strlen(str)+1);
strcpy(sp->shortcut[numb], str);
sss[0] = '\0';
for (i=1; i <= sp->numitems; i++) strcat(sss, sp->shortcut[i]);
fl_set_object_shortcut(ob, sss);
}
void fl_set_menu_item_mode(FL_OBJECT *ob, int numb, long mode)
/* Sets the display mode for the menu item */
{
SPEC *sp = ((SPEC *)(ob->spec));
sp->mode[numb] = mode;
}
void fl_show_menu_symbol(FL_OBJECT *ob, int show)
/* Makes the menu symbol visible or not */
{
SPEC *sp = ((SPEC *)(ob->spec));
sp->showsymbol = show;
fl_redraw_object(ob);
}
/*------------------------------------------*/
int fl_get_menu(FL_OBJECT *ob)
/* Returns the number of the menu item selected. */
{
SPEC *sp = ((SPEC *)(ob->spec));
return sp->val;
}
char *fl_get_menu_text(FL_OBJECT *ob)
/* Returns the text of the menu item selected. */
{
SPEC *sp = ((SPEC *)(ob->spec));
if (sp->val <= 0 || sp->val > sp->numitems) return NULL;
return sp->items[sp->val];
}